package calao.client.ui;

import java.util.Comparator;

import calao.client.Desktop;
import calao.client.Images;

import com.google.gwt.user.client.Command;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.MenuBar;
import com.google.gwt.user.client.ui.PopupPanel;
import com.google.gwt.user.client.ui.PushButton;

public abstract class SortableGrid
extends DataGrid
{

	final static Images images = Desktop.getDesktop().images;

	final static String STYLE_NAME = "calao-SortableGrid";

	final Comparator[] columnComparator;

	int[] rowMap;

	int sortColumn = -1;
	boolean sortReverse;

	class SortPanel extends PopupPanel {
		final MenuBar menu = new MenuBar(true);
		final int col;
		SortPanel(final int col) {
			super(true);
			this.col = col;
			add(menu);
			menu.addItem("Trier par ordre croissant", false, new Command() {
				public void execute() {
					hide();
					setSortColumn(col, false);
					refresh();
				}
			});
			menu.addItem("Trier par ordre décroissant", false, new Command() {
				public void execute() {
					hide();
					setSortColumn(col, true);
					refresh();
				}
			});
		}
	}

	class Header extends HorizontalPanel {
		final int col;
		final String text;
		PushButton button;
		Header(int col, String text) {
			this.col = col;
			this.text = text;
			addStyleName(Styles.HEADER);
			refresh();
		}
		void refresh() {
			if (getWidgetCount()>0) clear();
			add(new Label(text));
			if (columnComparator[col]!=null) {
				button = new PushButton(images.dropdown().createImage()) {
					protected void onClick() {
						SortPanel panel = new SortPanel(Header.this.col);
						int left = button.getAbsoluteLeft();
						int top = button.getAbsoluteTop() + button.getOffsetHeight();
						panel.setPopupPosition(left, top);
						panel.show();
					}
				};
				add(button);
			}
			else button = null;			
		}
	}

	protected SortableGrid(int columns)
	{
		super(columns);
		grid.addStyleName(STYLE_NAME);
		columnComparator = new Comparator[columns];
		initWidget(grid);
	}

	protected Object getViewData(int row, int col)
	{
		return getData(rowMap[row], col);
	}

	public void setSortColumn(int col, boolean reverse)
	{
		sortColumn = col;
		sortReverse = reverse;
	}

	public void refresh()
	{
		if (sortColumn!=-1) {
			Comparator comp = columnComparator[sortColumn];
			if (comp!=null) {
				onResize();
				for (int i=0; i<getRowCount(); i++) {
					for (int j=i+1; j<getRowCount(); j++) {
						Object iRowData = getViewData(i, sortColumn);
						Object jRowData = getViewData(j, sortColumn);
						if (sortReverse) {
							if (jRowData!=null) {
								if (iRowData==null || comp.compare(jRowData, iRowData)>0) {
									switchRows(i, j);
								}
							}
						}
						else if (iRowData!=null) {
							if (jRowData==null || comp.compare(iRowData, jRowData)>0) {
								switchRows(i, j);
							}
						}
					}
				}
			}
		}
		super.refresh();
	}

	private void switchRows(int i, int j) 
	{
		int iRowMap = rowMap[i];
		rowMap[i] = rowMap[j];
		rowMap[j] = iRowMap;		
	}

	public void setColumnComparator(int col, Comparator comparator)
	{
		columnComparator[col] = comparator;
		Header header = (Header)getHeaderWidget(col);
		if (header!=null) header.refresh();
	}

	public void setHeader(int col, String text)
	{
		setHeader(col, text!=null? new Header(col, text) : null);
	}

	protected void onResize()
	{
		if (rowMap==null || rowMap.length!=getRowCount()) {
			rowMap = new int[getRowCount()];
			for (int i=1; i<rowMap.length; i++) rowMap[i] = i;
		}
	}

}
